1 /*
2 Copyright: Marcelo S. N. Mancini (Hipreme|MrcSnm), 2018 - 2021
3 License:   [https://creativecommons.org/licenses/by/4.0/|CC BY-4.0 License].
4 Authors: Marcelo S. N. Mancini
5 
6 	Copyright Marcelo S. N. Mancini 2018 - 2021.
7 Distributed under the CC BY-4.0 License.
8    (See accompanying file LICENSE.txt or copy at
9 	https://creativecommons.org/licenses/by/4.0/
10 */
11 module hip.graphics.orthocamera;
12 import hip.hiprenderer.viewport;
13 import hip.hiprenderer;
14 import hip.math.matrix;
15 
16 /**
17 *   Orthographic Projection camera. 
18 *   A good resource to understand how orthographic projection works follows on:
19 *   http://learnwebgl.brown37.net/08_projections/projections_ortho.html
20 *
21 *   But basically:
22 *   1. Translate the center to the origin of the screen(top left)
23 *   2. Scale the screen size by 2 (remember that we lost the -1..0 range)
24 *   3. Alternate the handeness if necessary
25 */
26 class HipOrthoCamera
27 {
28     Matrix4 view;
29     Matrix4 proj;
30     Matrix4 viewProj;
31     float znear = 0.001f;
32     float zfar  = 100.0f;
33 
34     bool dirty = false;
35 
36     this()
37     {
38         view = Matrix4.identity;
39         proj = Matrix4.identity;
40         viewProj = Matrix4.identity;
41         updateFromViewport();
42     }
43     void updateFromViewport()
44     {
45         Viewport v = HipRenderer.getCurrentViewport();
46         proj = Matrix4.orthoLH(v.x, v.width, v.height, v.y, znear, zfar);
47         dirty = true;
48     }
49     void setSize(uint width, uint height)
50     {
51         proj = Matrix4.orthoLH(0, width, height, 0, znear, zfar);
52         dirty = true;
53     }
54     void translate(float x, float y, float z)
55     {
56         view = view.translate(x, y, z);
57         dirty = true;
58     }
59     void setScale(float x, float y, float z = 1)
60     {
61         view = view.scale((1/view[0])*x, (1/view[5])*y, (1/view[10])*z);
62         dirty = true;
63     }
64     void scale(float x, float y, float z = 0)
65     {
66         view = view.scale(x,y,z);
67         dirty = true;
68     }
69 
70     Matrix4 getMVP()
71     {
72         if(dirty)update();
73         return viewProj;
74     }
75 
76     void setPosition(float x, float y, float z = 0)
77     {
78         view = view.translate(-view[12]+x, -view[13]+y, -view[14]+z);
79         dirty = true;
80     }
81     pragma(inline, true)
82     @property float x(){return view[12];}
83     pragma(inline, true)
84     @property float y(){return view[13];}
85     pragma(inline, true)
86     @property float z(){return view[14];}
87 
88     void update()
89     {
90         viewProj = view*proj;
91         dirty = false;
92     }
93 }